#include <string.h>
#include <iostream>

using std::cout;
using std::endl;

class Base
{
public:
    Base(const char *pbase)
    : _pbase(new char[strlen(pbase) + 1]())
    {
        cout << "Base(const char *)" << endl;
        strcpy(_pbase, pbase);
    }

    virtual
    void print()
    {
        if(_pbase)
        {
            cout << "Base::_pbase = " << _pbase << endl;
        }
    }

    //如果将基类的析构函数设置为虚函数，那么派生类的析构函数也会
    //自动变为虚函数
    //编译器将基类的析构函数~destructor(),派生类的析构函数也是
    //~destructor()
    //编译器为什么能这么做呢？
    //因为对于任何一个类而言，析构函数只有一个，具有唯一性，不能
    //重载,这是唯一的一个名字不一样的重写
    virtual
    ~Base()
    {
        cout << "~Base()" << endl;
        if(_pbase)
        {
            delete [] _pbase;
            _pbase = nullptr;
        }
    }

private:
    char *_pbase;
};

class Derived
: public Base
{
public:
    Derived(const char *pbase, const char *pderived)
    : Base(pbase)
    , _pderived(new char[strlen(pderived) + 1]())
    {
        cout << "Derived(const char *, const char *)" << endl;
        strcpy(_pderived, pderived);
    }

    virtual
    void print()
    {
        if(_pderived)
        {
            cout << "Derived::_pderived = " << _pderived << endl;
        }
    }

    ~Derived()
    {
        cout << "~Derived()" << endl;
        if(_pderived)
        {
            delete [] _pderived;
            _pderived = nullptr;
        }
    }

private:
    char *_pderived;
};

int main(int argc, char **argv)
{
    Base *pb = new Derived("hello", "world");
    pb->print();

    //Q:内存泄漏
    /* delete dynamic_cast<Derived *>(pb);//ok */
    delete pb;//ok
    //1、执行析构函数,pb->~Base() pb->~Derived()
    //2、operator delete
    pb = nullptr;

    return 0;
}

